﻿namespace ScrumLite.Data
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using ScrumLite.Data;

    public class DefectStore : IDefectStore
    {
        public void Update(Defect entity)
        {
            using (ScrumLiteDataContext context = new ScrumLiteDataContext())
            {
                context.Log = new DebuggerWriter();
                var original = context.Defects.SingleOrDefault(r => r.id == entity.id);
                if (original != null)
                {
                    original.createdOn = entity.createdOn;
                    original.decision = entity.decision;
                    original.fk_deliverable = entity.fk_deliverable;
                    original.moniker = entity.moniker;
                    original.notes = entity.notes;
                    original.severity = entity.severity;
                    original.title = entity.title;
                    if (entity.triagedOn != null && original.triagedOn == null)
                    {
                        original.triagedOn = entity.triagedOn;
                    }

                    original.user_createdBy = entity.user_createdBy;
                    context.SubmitChanges();
                }
            }
        }

        public int RetrieveLastMoniker(Guid projectId)
        {
            using (ScrumLiteDataContext context = new ScrumLiteDataContext())
            {
                var query = from defect in context.Defects
                            where defect.Deliverable.pk_project == projectId
                            select defect.moniker;

                if (query.Count() > 0)
                {
                    return query.Max();
                }
                else
                {
                    return 0;
                }
            }
        }

        public void Add(Defect entity)
        {
            using (ScrumLiteDataContext context = new ScrumLiteDataContext())
            {
                context.Log = new DebuggerWriter();
                var defect = new Defect()
                {
                    id = entity.id,
                    createdOn = entity.createdOn,
                    decision = entity.decision,
                    fk_deliverable = entity.fk_deliverable,
                    user_createdBy = entity.user_createdBy,
                    triagedOn = entity.triagedOn,
                    title = entity.title,
                    severity = entity.severity,
                    notes = entity.notes,
                    moniker = entity.moniker,
                };

                context.Defects.InsertOnSubmit(defect);
                context.SubmitChanges();
            }
        }
        
        public Defect RetrieveDefect(Guid defectId)
        {
            using (ScrumLiteDataContext context = new ScrumLiteDataContext())
            {
                Defect result = context.Defects.SingleOrDefault(d => d.id == defectId);
                return result;
            }
        }

        public Defect RetrieveDefect(string projectId, int moniker)
        {
            using (ScrumLiteDataContext context = new ScrumLiteDataContext())
            {
                Defect result = context.Defects.SingleOrDefault(d => d.moniker == moniker && d.Deliverable.pk_project == new Guid(projectId));
                return result;
            }
        }

        public Defect[] RetrieveDefects(Guid projectId, bool triaged)
        {
            using (ScrumLiteDataContext context = new ScrumLiteDataContext())
            {
                IQueryable<Defect> query;
                if (triaged)
                {
                    query = (from defect in context.Defects
                             where defect.Deliverable.pk_project == projectId
                             orderby defect.Deliverable.releasedOn descending, defect.severity ascending
                             select defect);
                }
                else
                {
                    query = (from defect in context.Defects
                             where defect.Deliverable.pk_project == projectId &&
                             defect.triagedOn == null
                             orderby defect.Deliverable.releasedOn descending, defect.severity ascending
                             select defect);
                }
                return query.ToArray();
            }
        }
        
        public void Delete(Guid defectId)
        {
            using (ScrumLiteDataContext context = new ScrumLiteDataContext())
            {
                Defect defect = context.Defects.SingleOrDefault(d => d.id == defectId);
                context.Defects.DeleteOnSubmit(defect);
                context.SubmitChanges();
            }
        }
    }
}

